package com.cuz.daileetcode.bat100;

public class 字符串交错组成问题 {

    public static void main(String[] args) {
        String s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc";
        System.out.println(isInterleave1(s1, s2, s3));
        System.out.println(isInterleave2(s1, s2, s3));
        System.out.println(isInterleave3(s1, s2, s3));
    }

    public static boolean isInterleave3(String s1, String s2, String s3) {
        if (s1.length() + s2.length() != s3.length()) {
            return false;
        }
        char[] chars1 = s1.toCharArray();
        char[] chars2 = s2.toCharArray();
        char[] chars3 = s3.toCharArray();
        int len1 = chars1.length;
        int len2 = chars2.length;
        boolean[] dp = new boolean[len1 + 1];
        //为0 表示 “” 和“” 是否交错组成“”
        dp[0] = true;
        //如果前i个字符全部来自s1 那么s1 是否和s3前i个字符匹配
        for (int i = 1; i <= len1; i++) {
            if (chars1[i - 1] != chars3[i - 1]) {
                break;
            }
            dp[i] = true;
        }
        for (int i = 0; i <= len1; i++) {
            for (int j = 0; j <= len2; j++) {
                if (i == 0 && j == 0) {
                    dp[i] = true;
                    continue;
                }
                if (i == 0) {
                    dp[j] = dp[j] || chars2[j - 1] == chars3[j - 1];
                    continue;
                }
                if (j == 0) {
                    dp[i] = dp[i] || chars1[i - 1] == chars3[i - 1];
                    continue;
                }
                if (chars1[i - 1] == chars3[i - 1]) {
                    dp[i] = dp[i] || dp[i - 1];
                }
                if (chars1[j - 1] == chars3[j - 1]) {
                    dp[j] = dp[j] || dp[j - 1];
                }
            }
        }
        return dp[len1];
    }

    public static boolean isInterleave2(String s1, String s2, String s3) {
        if (s1.length() + s2.length() != s3.length()) {
            return false;
        }
        char[] chars1 = s1.toCharArray();
        char[] chars2 = s2.toCharArray();
        char[] chars3 = s3.toCharArray();
        int len1 = chars1.length;
        int len2 = chars2.length;
        boolean[][] dp = new boolean[len1 + 1][len2 + 1];
        //为0 表示 “” 和“” 是否交错组成“”
        dp[0][0] = true;
        //如果前i个字符全部来自s1 那么s1 是否和s3前i个字符匹配
        for (int i = 1; i <= len1; i++) {
            if (chars1[i - 1] != chars3[i - 1]) {
                break;
            }
            dp[i][0] = true;
        }
        for (int j = 1; j <= len2; j++) {
            if (chars2[j - 1] != chars3[j - 1]) {
                break;
            }
            dp[0][j] = true;
        }
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                if (chars1[i - 1] == chars3[i + j - 1]) {
                    dp[i][j] = dp[i - 1][j];
                }
                if (chars2[j - 1] == chars3[i + j - 1]) {
                    dp[i][j] = dp[i][j] || dp[i][j - 1];
                }
            }
        }
        return dp[len1][len2];
    }

    //s1 s2 是否交错组成s3
    public static boolean isInterleave1(String s1, String s2, String s3) {
        if (s1.length() + s2.length() != s3.length()) {
            return false;
        }
        char[] chars1 = s1.toCharArray();
        char[] chars2 = s2.toCharArray();
        char[] chars3 = s3.toCharArray();
        return process(chars1, chars2, chars3, chars1.length, chars2.length);
    }

    private static boolean process(char[] chars1, char[] chars2, char[] chars3, int i, int j) {
        //i j  为0 表示 “” 和“” 是否交错组成“”
        if (i == 0 && j == 0) {
            return true;
        }
        //如果前j个字符全部来自s2 那么s2 是否和s3前j个字符匹配
        if (i == 0) {
            for (int index = 0; index < j; index++) {
                if (chars3[index] != chars2[index]) {
                    return false;
                }
            }
            return true;
        }
        //如果前i个字符全部来自s1 那么s1 是否和s3前i个字符匹配
        if (j == 0) {
            for (int index = 0; index < i; index++) {
                if (chars3[index] != chars1[index]) {
                    return false;
                }
            }
            return true;
        }
        //如果s1 末尾字符等于 s3末尾字符 那么 去掉s1 末尾字符去和 s3去掉末尾字符比对
        if (chars1[i - 1] == chars3[i + j - 1]) {
            return process(chars1, chars2, chars3, i - 1, j);
        }
        //如果s2 末尾字符等于 s3末尾字符 那么 去掉s2 末尾字符去和 s3去掉末尾字符比对
        if (chars2[j - 1] == chars3[i + j - 1]) {
            return process(chars1, chars2, chars3, i, j - 1);
        }
        return false;
    }


}
